package dcedit.util;

// Import Java SDK Classes
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

import java.io.File;
import java.io.IOException;

// Import Fife Classes
import org.fife.ui.rsyntaxtextarea.*;
import org.fife.ui.rtextarea.*;

/** Class DCTextEditor */
public class DCTextEditor extends RTextScrollPane {
   /** Serial Version UID version for serializable classes */
   public static final long serialVersionUID = 1305048921027L;

   /** Constructor */
   public DCTextEditor() {
      this(SyntaxStyle.JAVA);
   } // END constructor

   /** Constructor */
   public DCTextEditor(final SyntaxStyle SYNTAX_STYLE) {
      super(new TextEditorPane(TextEditorPane.INSERT_MODE,false));

      this.getTextArea().setDocument(new RSyntaxDocument(SYNTAX_STYLE.getValue()));
      this.getTextArea().setTabsEmulated(true);
      this.getTextArea().setTabSize(3);
      this.setAutoIndentEnabled(true);

      this.setLineNumbersEnabled(true);
      this.setIconRowHeaderEnabled(false);

      this.setVerticalScrollBarPolicy(RTextScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
      this.setHorizontalScrollBarPolicy(RTextScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

      final Gutter GUTTER = this.getGutter();
      this.getTextArea().addCaretListener(new CaretListener() {
         public void caretUpdate(CaretEvent ce) {
            GUTTER.setLineNumberFont(GUTTER.getLineNumberFont());
         } // END caretUpdate
      });
   } // END constructor

   /** setFG method */
   public void setFG(Color fgColor) {
      this.getTextArea().setForeground(fgColor);
      this.getTextArea().setCaretColor(fgColor);
      this.getGutter().setBorderColor(fgColor);
      this.getGutter().setLineNumberColor(fgColor);
   } // END setFG

   /** setBG method */
   public void setBG(Color bgColor) {
      this.getTextArea().setBackground(bgColor);
      this.getGutter().setBackground(bgColor);
   } // END setBG

   /** setHL method */
   public void setHL(Color hlColor) {
      this.getTextArea().setCurrentLineHighlightColor(hlColor);
   } // END setHL

   /** setFont method */
   public void setFont(final Font FONT) {
      // Run within a new thread.
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            getTextArea().setFont(FONT);
            getGutter().setLineNumberFont(FONT);
         } // END run
      });
   } // END setFont

   /** save method */
   public void save() throws IOException {
      this.getTextArea().save();
   } // END save

   /** saveAs method */
   public void saveAs(File location) throws IOException {
      this.getTextArea().saveAs(FileLocation.create(location));
   } // END saveAs

   /** saveAs method */
   public void saveAs(FileLocation location) throws IOException {
      this.getTextArea().saveAs(location);
   } // END saveAs

   /** load method */
   public void load(File location,String defaultEnc) throws IOException {
      this.getTextArea().load(FileLocation.create(location), defaultEnc);
   } // END load

   /** load method */
   public void load(FileLocation location,String defaultEnc) throws IOException {
      this.getTextArea().load(location, defaultEnc);
   } // END load

   /** getText method */
   public String getText() {
      return this.getTextArea().getText();
   } // END getText

   /** setText method */
   public void setText(String text) {
      this.getTextArea().setText(text);
   } // END setText

   /** prependText method */
   public void prependText(String text) {
      setText(text + getText());
   } // END prependText

   /** appendText method */
   public void appendText(final String text) {
      this.getTextArea().append(text);
   } // END appendText

   /** isEmpty method */
   public boolean isEmpty() {
      return this.getText().isEmpty();
   } // END isEmpty

   /** isDirty method */
   public boolean isDirty() {
      return this.getTextArea().isDirty();
   } // END isDirty

   /** getTextArea method */
   public TextEditorPane getTextArea() {
      return (TextEditorPane)super.getTextArea();
   } // END getTextArea

   /** getDocument method */
   public Document getDocument() {
      return this.getTextArea().getDocument();
   } // END getDocument

   /** getCaretPosition method */
   public int getCaretPosition() {
      return this.getTextArea().getCaretPosition();
   } // END getCaretPosition

   /** setAutoIndentEnabled method */
   public void setAutoIndentEnabled(boolean enabled) {
      this.getTextArea().setAutoIndentEnabled(enabled);
   } // END setAutoIndentEnabled

   /** setSyntaxStyle method */
   public void setSyntaxStyle(final SyntaxStyle SYNTAX_STYLE) {
      final RSyntaxDocument DOCUMENT = (RSyntaxDocument)this.getDocument();
      DOCUMENT.setSyntaxStyle(SYNTAX_STYLE.getValue());
   } // END setSyntaxStyle

   /** Enum SyntaxStyle */
   public enum SyntaxStyle {
      // ENUM         DISPLAY            VALUE
      ACTION_SCRIPT(  "Action Script",   SyntaxConstants.SYNTAX_STYLE_ACTIONSCRIPT),
      ASSEMBLER_X86(  "Assembler X86",   SyntaxConstants.SYNTAX_STYLE_ASSEMBLER_X86),
      BB_CODE(        "BB Code",         SyntaxConstants.SYNTAX_STYLE_BBCODE),
      C(              "C",               SyntaxConstants.SYNTAX_STYLE_C),
      CLOJURE(        "Clojure",         SyntaxConstants.SYNTAX_STYLE_CLOJURE),
      CPP(            "C++",             SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS),
      C_SHARP(        "C#",              SyntaxConstants.SYNTAX_STYLE_CSHARP),
      CSS(            "CSS",             SyntaxConstants.SYNTAX_STYLE_CSS),
      DELPHI(         "Delphi",          SyntaxConstants.SYNTAX_STYLE_DELPHI),
      FORTRAN(        "FORTRAN",         SyntaxConstants.SYNTAX_STYLE_FORTRAN),
      GROOVY(         "Groovy",          SyntaxConstants.SYNTAX_STYLE_GROOVY),
      HTML(           "HTML",            SyntaxConstants.SYNTAX_STYLE_HTML),
      JAVA(           "Java",            SyntaxConstants.SYNTAX_STYLE_JAVA),
      JAVA_SCRIPT(    "JavaScript",      SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT),
      JSP(            "JSP",             SyntaxConstants.SYNTAX_STYLE_JSP),
      LISP(           "LISP",            SyntaxConstants.SYNTAX_STYLE_LISP),
      LUA(            "Lua",             SyntaxConstants.SYNTAX_STYLE_LUA),
      MAKE_FILE(      "MakeFile",        SyntaxConstants.SYNTAX_STYLE_MAKEFILE),
      MXML(           "MXML",            SyntaxConstants.SYNTAX_STYLE_MXML),
      NONE(           "None",            SyntaxConstants.SYNTAX_STYLE_NONE),
      PERL(           "Perl",            SyntaxConstants.SYNTAX_STYLE_PERL),
      PHP(            "PHP",             SyntaxConstants.SYNTAX_STYLE_PHP),
      PROPERTIES_FILE("Properties File", SyntaxConstants.SYNTAX_STYLE_PROPERTIES_FILE),
      PYTHON(         "Python",          SyntaxConstants.SYNTAX_STYLE_PYTHON),
      RUBY(           "Ruby",            SyntaxConstants.SYNTAX_STYLE_RUBY),
      SAS(            "SAS",             SyntaxConstants.SYNTAX_STYLE_SAS),
      SCALA(          "Scala",           SyntaxConstants.SYNTAX_STYLE_SCALA),
      SQL(            "SQL",             SyntaxConstants.SYNTAX_STYLE_SQL),
      TCL(            "TCL",             SyntaxConstants.SYNTAX_STYLE_TCL),
      UNIX_SHELL(     "Unix Shell",      SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL),
      BATCH_FILE(     "Batch File",      SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH),
      XML(            "XML",             SyntaxConstants.SYNTAX_STYLE_XML);

      /** display field */
      private String display;

      /** value field */
      private String value;

      /** Constructor */
      private SyntaxStyle(String display,String value) {
         this.display = display;
         this.value = value;
      } // END constructor

      /** getDisplay method */
      public String getDisplay() {
         return display;
      } // END getDisplay

      /** getValue method */
      public String getValue() {
         return value;
      } // END getValue

      /** toString method */
      public String toString() {
         return getDisplay();
      } // END toString
   } // END enum SyntaxStyle
} // END class DCTextEditor
